package mylab.io.core.codec;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;

import java.net.InetSocketAddress;
import java.util.List;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import lombok.extern.slf4j.Slf4j;
import mylab.io.base.model.Endpoint;
import mylab.io.base.model.Msg;
import mylab.io.base.model.impl.SocketEndpoint;
import mylab.io.base.util.TerminalUtil;


@Slf4j
@ChannelHandler.Sharable
public class UdpEncoder<M extends Msg> extends SimpleEncoder<M> {
    public static final String HANDLER_NAME = UdpEncoder.class.getSimpleName();

    public UdpEncoder(MsgResolver<M, ByteBuf> msgResolver) {
        super(msgResolver);
    }

    @Override
    protected void encode(ChannelHandlerContext ctx, Msg msg, List<Object> out) throws Exception {
        super.encode(ctx, msg, out);

        Preconditions.checkNotNull(msg.getTo(), "udp 报文需要设置目标地址");
        Preconditions.checkState(TerminalUtil.isValid(msg.getTo()), "udp 报文目标地址无效");

        Endpoint endpoint = msg.getTo().getEndpoint();
        if (endpoint instanceof SocketEndpoint socketEndpoint) {
            InetSocketAddress address = socketEndpoint.getAddress();
            //build DatagramPacket
            List<Object> raw = Lists.newArrayList(out);
            out.clear();
            for (Object obj : raw) {
                if (obj instanceof ByteBuf buf) {
                    out.add(new DatagramPacket(buf, address));
                }
            }
        } else {
            log.warn("not support endpoint");
        }

    }
}
